<template>
  <div>
    <el-dialog title="图片属性设置" :visible.sync="imageDialogVisible" width="500px" :close-on-click-modal="false"
      :before-close="handleDialogClose" :append-to-body="true">
      <el-form :model="imageForm" label-width="100px" ref="imageForm">
        <el-form-item label="上传图片">
          <el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleDialogUploadSuccess"
            :on-error="handleUploadError" name="file" :show-file-list="false" :headers="headers">
            <el-button size="small" type="primary">选择图片</el-button>
            <div slot="tip" class="el-upload__tip">
              支持 JPG、PNG、SVG 格式，最小 {{ fileSize }}MB
            </div>
          </el-upload>

          <div v-if="imageForm.url" class="image-preview">
            <img :src="imageForm.url" :alt="imageForm.alt" class="preview-img" :style="{
              maxWidth: '100%',
              border: imageForm.border ? imageForm.border : 'none',
              margin: imageForm.margin ? imageForm.margin : 0
            }">
          </div>
        </el-form-item>

        <el-form-item label="宽度">
          <el-input v-model="imageForm.width" @input="handleWidthChange" placeholder="输入宽度，高度将自动调整">
            <template slot="append">
              <el-select v-model="imageForm.widthUnit" @change="handleWidthChange" style="width: 60px;">
                <el-option label="px" value="px"></el-option>
                <el-option label="%" value="%"></el-option>
              </el-select>
            </template>
          </el-input>
        </el-form-item>

        <el-form-item label="高度">
          <el-input v-model="imageForm.height" @input="handleHeightChange" placeholder="输入高度，宽度将自动调整">
            <template slot="append">
              <el-select v-model="imageForm.heightUnit" @change="handleHeightChange" style="width: 60px;">
                <el-option label="px" value="px"></el-option>
                <el-option label="%" value="%"></el-option>
                <el-option label="auto" value="auto"></el-option>
              </el-select>
            </template>
          </el-input>
        </el-form-item>

        <el-form-item label="保持比例">
          <el-switch v-model="imageForm.keepAspectRatio" @change="handleAspectRatioChange"></el-switch>
          <span style="margin-left: 10px; color: #909399; font-size: 12px;">开启后修改一个维度时另一个维度会自动调整</span>
        </el-form-item>

        <el-form-item label="边框">
          <el-input v-model="imageForm.border"></el-input>
        </el-form-item>

        <el-form-item label="边距">
          <el-input v-model="imageForm.margin"></el-input>
        </el-form-item>

        <el-form-item label="图片描述">
          <el-input v-model="imageForm.alt"></el-input>
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="handleDialogClose">取消</el-button>
        <el-button type="primary" @click="confirmImageSettings">确定插入</el-button>
      </div>
    </el-dialog>

    <div
      v-show="contextMenuVisible"
      :style="contextMenuStyle"
      class="context-menu"
      @click="onEditImageMenuClick"
    >
      编辑图片
    </div>

    <el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess"
      :on-error="handleUploadError" name="file" :show-file-list="false" :headers="headers" style="display: none"
      ref="upload" v-if="this.type == 'url'">
    </el-upload>
    <div class="editor" ref="editor" :style="styles"></div>
  </div>
</template>

<script>
import Quill from "quill";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import { getToken } from "@/utils/auth";
import { uploadContentImage } from "@/api/uncheck/uncheck";
import ImageResize from 'quill-image-resize-module'

Quill.register('modules/imageResize', ImageResize);

const Size = Quill.import('attributors/style/size');
const Font = Quill.import('formats/font');

Size.whitelist = ['12px', '14px', '16px', '20px', '24px', '32px'];
Quill.register(Size, true);

Font.whitelist = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial'];
Quill.register(Font, true);

const style = document.createElement('style');
style.innerHTML = `
  .ql-font-SimSun { font-family: "SimSun", serif; }
  .ql-font-SimHei { font-family: "SimHei", sans-serif; }
  .ql-font-Microsoft-YaHei { font-family: "Microsoft YaHei", sans-serif; }
  .ql-font-KaiTi { font-family: "KaiTi", serif; }
  .ql-font-FangSong { font-family: "FangSong", serif; }
  .ql-font-Arial { font-family: "Arial", sans-serif; }
`;
document.head.appendChild(style);

export default {
  name: "Editor",
  props: {
    value: { type: String, default: "" },
    height: { type: Number, default: null },
    minHeight: { type: Number, default: null },
    readOnly: { type: Boolean, default: false },
    fileSize: { type: Number, default: 1 },
    type: { type: String, default: "url" }
  },
  data() {
    return {
      uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload",
      headers: { Authorization: "Bearer " + getToken() },
      quill: null,
      content: "",
      options: {
        theme: "snow",
        bounds: document.body,
        debug: "warn",
        modules: {
          toolbar: [
            ["bold", "italic", "underline"],
            ["blockquote"],
            [{ list: "ordered" }, { list: "bullet" }],
            [{ indent: "-1" }, { indent: "+1" }],
            [{ 'font': ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial'] }],
            [{ 'size': ['12px', '14px', '16px', '20px', '24px', '32px'] }],
            [{ color: [] }, { background: [] }],
            [{ align: [] }],
            ["clean"],
            ["link", "image"],
            ["formatAll"]
          ],
          imageResize: {
            displayStyles: {
              backgroundColor: 'black',
              borderStyle: 'solid',
              borderColor: 'black',
              color: 'white'
            },
            modules: ['Resize', 'DisplaySize', 'Toolbar']
          }
        },
        placeholder: "请输入内容",
        readOnly: this.readOnly,
      },
      imageDialogVisible: false,
      imageForm: {
        url: "",
        width: "",
        height: "",
        widthUnit: "px",
        heightUnit: "px",
        keepAspectRatio: true,
        originalWidth: 0,
        originalHeight: 0,
        border: "",
        margin: "",
        alt: ""
      },
      selectionIndex: 0,
      isFormatted: false,
      originalContent: "",
      contextMenuVisible: false,
      contextMenuStyle: {},
      contextMenuImageNode: null,
      contextMenuImageIndex: 0,
      imageResizeObserver: null,
      currentResizingImage: null,
    };
  },
  computed: {
    styles() {
      let style = {};
      if (this.minHeight) style.minHeight = `${this.minHeight}px`;
      if (this.height) style.height = `${this.height}px`;
      return style;
    },
  },
  watch: {
    value: {
      handler(val) {
        if (val !== this.content) {
          this.content = val === null ? "" : val;
          if (this.quill) {
            this.quill.clipboard.dangerouslyPasteHTML(this.content);
          }
        }
      },
      immediate: true,
    },
  },
  mounted() {
    this.init();
    this.$nextTick(() => {
      const btn = document.querySelector('.ql-formatAll');
      if (btn) {
        btn.addEventListener('click', this.handleFormatAll);
      }
    });
    document.addEventListener('click', this.hideContextMenu);
    document.addEventListener('scroll', this.hideContextMenu, true);
    document.addEventListener('contextmenu', this.hideContextMenu, true);
    this.$nextTick(() => {
      const editorEl = this.$refs.editor;
      if (editorEl) {
        editorEl.addEventListener('contextmenu', this.handleEditorContextMenu, false);
      }
      document.addEventListener('click', this.hideContextMenu, false);
    });
  },
  beforeDestroy() {
    const btn = document.querySelector('.ql-formatAll');
    if (btn) {
      btn.removeEventListener('click', this.handleFormatAll);
    }
    this.quill = null;
    document.removeEventListener('click', this.hideContextMenu);
    document.removeEventListener('scroll', this.hideContextMenu, true);
    document.removeEventListener('contextmenu', this.hideContextMenu, true);

    if (this.imageResizeObserver) {
      this.imageResizeObserver.disconnect();
      this.imageResizeObserver = null;
    }
  },
  methods: {
    init() {
      const editor = this.$refs.editor;
      this.quill = new Quill(editor, this.options);

      if (this.type == 'url') {
        const toolbar = this.quill.getModule("toolbar");
        toolbar.addHandler("image", () => {
          const selection = this.quill.getSelection();
          if (selection) {
            this.selectionIndex = selection.index;
          }

          this.imageForm = {
            url: "",
            width: "",
            height: "",
            widthUnit: "px",
            heightUnit: "px",
            keepAspectRatio: true,
            originalWidth: 0,
            originalHeight: 0,
            border: "",
            margin: "",
            alt: ""
          };

          this.imageDialogVisible = true;
        });
      }

      this.quill.clipboard.dangerouslyPasteHTML(this.content);
      this.normalizeImagesInEditor();

      this.quill.on("text-change", (delta, oldDelta, source) => {
        const html = this.$refs.editor.children[0].innerHTML;
        const text = this.quill.getText();
        this.content = html;
        this.$emit("input", html);
        this.$emit("on-change", { html, text, quill: this.quill });
      });

      this.quill.on("selection-change", (range, oldRange, source) => {
        if (!range && oldRange) {
          const html = this.$refs.editor.children[0].innerHTML;
          this.content = html;
          this.$emit("input", html);
          this.$emit("on-change", { html, text: this.quill.getText(), quill: this.quill });
        }
      });

      this.quill.root.addEventListener('DOMSubtreeModified', () => {
        setTimeout(() => {
          this.normalizeImagesInEditor();

          const html = this.$refs.editor.children[0].innerHTML;
          if (html !== this.content) {
            this.content = html;
            this.$emit("input", html);
            this.$emit("on-change", { html, text: this.quill.getText(), quill: this.quill });
          }
        }, 0);
      });

      this.setupImageResizeObserver();
      this.setupImageResizeHandlers();

      this.$nextTick(() => {
        const editorEl = this.$refs.editor;
        if (editorEl) {
          editorEl.addEventListener('contextmenu', this.handleEditorContextMenu, false);
        }
      });
    },

    handleFormatAll() {
      const quill = this.quill;
      const range = quill.getSelection();

      if (!range) {
        // 如果没有选中内容，处理整个文档
        this.formatEntireDocument(quill);
      } else {
        // 如果选中了内容，只处理选中的部分
        this.formatSelectedContent(quill, range);
      }

      // 触发更新
      this.$nextTick(() => {
        const html = this.$refs.editor.children[0].innerHTML;
        this.content = html;
        this.$emit("input", html);
        this.$emit("on-change", { html, text: this.quill.getText(), quill: this.quill });
      });
    },

    formatEntireDocument(quill) {
      const delta = quill.getContents();
      const newDelta = new Delta();

      delta.ops.forEach(op => {
        if (op.insert && typeof op.insert === 'string') {
          // 对每个段落应用首行缩进
          const lines = op.insert.split('\n');
          const formattedLines = lines.map((line, index) => {
            if (line.trim() === '') return line;

            // 如果是第一行或者段落开头，添加缩进
            if (index === 0 || op.attributes && op.attributes['paragraph']) {
              return `    ${line}`; // 使用4个空格作为缩进
            }
            return line;
          });

          newDelta.insert(formattedLines.join('\n'), op.attributes);
        } else {
          newDelta.insert(op.insert, op.attributes);
        }
      });

      quill.setContents(newDelta);
    },

    formatSelectedContent(quill, range) {
      const [line, offset] = quill.getLine(range.index);
      const delta = quill.getContents(range.index, range.length);

      // 获取选中的文本
      const selectedText = quill.getText(range.index, range.length);

      // 如果选中的是整个段落
      if (selectedText.trim() !== '' && (selectedText.includes('\n') || range.length > selectedText.length)) {
        // 处理多行选中
        const lines = selectedText.split('\n');
        const formattedLines = lines.map((line, index) => {
          if (line.trim() === '') return line;
          // 对每行添加缩进
          return `    ${line}`;
        });

        // 替换选中的内容
        quill.deleteText(range.index, range.length);
        quill.insertText(range.index, formattedLines.join('\n'));
      } else {
        // 处理单个段落
        const paragraph = quill.getLeaf(range.index)[0].domNode.parentNode;
        if (paragraph && paragraph.tagName === 'P') {
          // 检查是否已经有缩进
          const hasIndent = paragraph.style.textIndent ||
            paragraph.getAttribute('data-indent') ||
            paragraph.textContent.startsWith('    ');

          if (!hasIndent) {
            // 添加缩进样式
            paragraph.style.textIndent = '2em';
            paragraph.setAttribute('data-indent', 'true');
          }
        }
      }
    },

    handleEditorContextMenu(e) {
      let target = e.target;
      if (target && target.tagName === 'IMG') {
        e.preventDefault();
        this.contextMenuImageNode = target;

        let blot = Quill.find(target);
        let index = 0;
        if (blot) {
          index = blot.offset(this.quill.scroll);
        }
        this.contextMenuImageIndex = index;

        this.contextMenuStyle = {
          position: 'fixed',
          left: e.clientX + 'px',
          top: e.clientY + 'px',
          zIndex: 9999
        };
        this.contextMenuVisible = true;
      } else {
        this.hideContextMenu();
      }
    },

    hideContextMenu() {
      this.contextMenuVisible = false;
    },

    onEditImageMenuClick() {
      this.hideContextMenu();

      if (this.contextMenuImageNode) {
        const img = this.contextMenuImageNode;
        this.selectionIndex = this.contextMenuImageIndex;

        let width = img.getAttribute('width') || '';
        let height = img.getAttribute('height') || '';
        let border = img.getAttribute('border') || '';
        let margin = img.getAttribute('margin') || '';
        let alt = img.getAttribute('alt') || '';
        let url = img.getAttribute('src') || '';
        let keepHeight = img.getAttribute('data-keep-height');

        if (img.style) {
          if (img.style.width) width = img.style.width;
          if (img.style.height) height = img.style.height;
          if (img.style.border) border = img.style.border;
          if (img.style.margin) margin = img.style.margin;
        }

        let widthUnit = 'px';
        let heightUnit = 'px';
        let widthValue = '';
        let heightValue = '';

        if (width) {
          if (width.includes('%')) {
            widthUnit = '%';
            widthValue = width.replace('%', '');
          } else if (width.includes('px')) {
            widthUnit = 'px';
            widthValue = width.replace('px', '');
          } else {
            widthValue = width;
          }
        }

        if (height) {
          if (height.includes('%')) {
            heightUnit = '%';
            heightValue = height.replace('%', '');
          } else if (height.includes('px')) {
            heightUnit = 'px';
            heightValue = height.replace('px', '');
          } else if (height === 'auto') {
            heightUnit = 'auto';
            heightValue = 'auto';
          } else {
            heightValue = height;
          }
        }

        this.imageForm = {
          url: url,
          width: widthValue,
          height: heightValue,
          widthUnit: widthUnit,
          heightUnit: heightUnit,
          keepAspectRatio: true,
          originalWidth: img.naturalWidth || 0,
          originalHeight: img.naturalHeight || 0,
          border: border,
          margin: margin,
          alt: alt
        };

        if (this.imageForm.originalWidth === 0 || this.imageForm.originalHeight === 0) {
          this.getImageOriginalSize(url);
        }

        this.imageDialogVisible = true;
      }
    },

    handleDialogUploadSuccess(res) {
      if (res.code == 200) {
        this.imageForm.url = process.env.VUE_APP_BASE_API + res.fileName;
        this.$message.success("图片上传成功");
        this.getImageOriginalSize(this.imageForm.url);
      } else {
        this.$message.error("图片上传失败: " + (res.msg || "未知错误"));
      }
    },

    getImageOriginalSize(imageUrl) {
      const img = new Image();
      img.onload = () => {
        this.imageForm.originalWidth = img.naturalWidth;
        this.imageForm.originalHeight = img.naturalHeight;
        
        // 设置默认尺寸，限制最大宽度为1500px
        let defaultWidth = this.imageForm.originalWidth;
        let defaultHeight = this.imageForm.originalHeight;
        
        if (defaultWidth > 1500) {
          const aspectRatio = defaultHeight / defaultWidth;
          defaultWidth = 1500;
          defaultHeight = Math.round(1500 * aspectRatio);
        }
        
        if (!this.imageForm.width) {
          this.imageForm.width = defaultWidth.toString();
        }
        if (!this.imageForm.height) {
          this.imageForm.height = defaultHeight.toString();
        }
      };
      img.src = imageUrl;
    },

    handleWidthChange() {
      const widthValue = parseFloat(this.imageForm.width);
      if (!isNaN(widthValue) && widthValue > 0) {
        // 限制最大宽度为1500px
        if (widthValue > 1500) {
          this.imageForm.width = '1500';

        }
        
        if (this.imageForm.keepAspectRatio && this.imageForm.originalWidth > 0 && this.imageForm.originalHeight > 0) {
          const finalWidth = Math.min(widthValue, 1500);
          const aspectRatio = this.imageForm.originalHeight / this.imageForm.originalWidth;
          const newHeight = Math.round(finalWidth * aspectRatio);
          this.imageForm.height = newHeight.toString();
        }
      }
    },

    handleHeightChange() {
      if (this.imageForm.keepAspectRatio && this.imageForm.originalWidth > 0 && this.imageForm.originalHeight > 0) {
        const heightValue = parseFloat(this.imageForm.height);
        if (!isNaN(heightValue) && heightValue > 0) {
          const aspectRatio = this.imageForm.originalWidth / this.imageForm.originalHeight;
          const newWidth = Math.round(heightValue * aspectRatio);
          
          // 如果计算出的宽度超过1500px，则按比例缩小
          if (newWidth > 1500) {
            const scaleFactor = 1500 / newWidth;
            this.imageForm.width = '1500';
            this.imageForm.height = Math.round(heightValue * scaleFactor).toString();
          } else {
            this.imageForm.width = newWidth.toString();
          }
        }
      }
    },

    handleAspectRatioChange() {
      if (this.imageForm.keepAspectRatio && this.imageForm.originalWidth > 0 && this.imageForm.originalHeight > 0) {
        // 重新计算当前尺寸
        this.handleWidthChange();
      }
    },

    normalizeImagesInEditor() {
      const images = this.$refs.editor.querySelectorAll('img');
      images.forEach(img => {
        // 只保留width属性，移除height属性和CSS样式
        const height = img.getAttribute('height');
        const keepHeight = img.getAttribute('data-keep-height');

        img.style.width = '';
      });
    },

    setupImageResizeObserver() {
      // 创建MutationObserver来监听DOM变化
      this.imageResizeObserver = new MutationObserver((mutations) => {
        let shouldUpdate = false;

        mutations.forEach((mutation) => {
          // 监听属性变化
          if (mutation.type === 'attributes') {
            const target = mutation.target;
            if (target.tagName === 'IMG') {
              // 检查是否添加了height属性，只清理height
              if (mutation.attributeName === 'height') {
                this.normalizeImageAttributes(target);
                shouldUpdate = true;
              }
            }
          }

          // 监听子节点变化
          if (mutation.type === 'childList') {
            mutation.addedNodes.forEach((node) => {
              if (node.nodeType === Node.ELEMENT_NODE) {
                if (node.tagName === 'IMG') {
                  this.normalizeImageAttributes(node);
                  shouldUpdate = true;
                } else {
                  // 检查新增节点中的图片
                  const images = node.querySelectorAll ? node.querySelectorAll('img') : [];
                  images.forEach(img => {
                    this.normalizeImageAttributes(img);
                    shouldUpdate = true;
                  });
                }
              }
            });
          }
        });

        // 如果有变化，更新内容
        if (shouldUpdate) {
          setTimeout(() => {
            const html = this.$refs.editor.children[0].innerHTML;
            this.content = html;
            this.$emit("input", html);
            this.$emit("on-change", { html, text: this.quill.getText(), quill: this.quill });
          }, 50);
        }
      });

      // 开始观察
      this.imageResizeObserver.observe(this.$refs.editor, {
        attributes: true,
        childList: true,
        subtree: true,
        attributeFilter: ['height', 'style']
      });
    },

    normalizeImageAttributes(img) {
      if (!img || img.tagName !== 'IMG') return;

      const width = img.getAttribute('width');
      const height = img.getAttribute('height');
      const keepHeight = img.getAttribute('data-keep-height');

      img.style.width = '';
    },

    setupImageResizeHandlers() {
      // 监听鼠标按下事件，准备缩放
      this.quill.root.addEventListener('mousedown', (e) => {
        if (e.target.tagName === 'IMG') {
          this.currentResizingImage = e.target;
          // 确保图片只使用CSS样式
          this.normalizeImageAttributes(e.target);
        }
      });

      // 监听鼠标移动事件，实时处理缩放
      this.quill.root.addEventListener('mousemove', (e) => {
        if (this.currentResizingImage && e.target.tagName === 'IMG') {
          // 实时清理HTML属性
          this.normalizeImageAttributes(e.target);
        }
      });

      // 监听鼠标释放事件，完成缩放
      this.quill.root.addEventListener('mouseup', (e) => {
        if (this.currentResizingImage) {
          // 最终清理HTML属性
          this.normalizeImageAttributes(this.currentResizingImage);

          // 延迟更新内容，确保quill-image-resize-module完成操作
          setTimeout(() => {
            const html = this.$refs.editor.children[0].innerHTML;
            this.content = html;
            this.$emit("input", html);
            this.$emit("on-change", { html, text: this.quill.getText(), quill: this.quill });
          }, 100);

          this.currentResizingImage = null;
        }
      });

      // 监听拖拽结束事件
      this.quill.root.addEventListener('dragend', (e) => {
        if (e.target.tagName === 'IMG') {
          this.normalizeImageAttributes(e.target);
          setTimeout(() => {
            const html = this.$refs.editor.children[0].innerHTML;
            this.content = html;
            this.$emit("input", html);
            this.$emit("on-change", { html, text: this.quill.getText(), quill: this.quill });
          }, 100);
        }
      });
    },

    confirmImageSettings() {
      if (!this.imageForm.url) {
        this.$message.error("请先上传图片");
        return;
      }

      // 确保宽度不超过1500px
      let finalWidth = this.imageForm.width;
      let finalHeight = this.imageForm.height;
      
      if (finalWidth) {
        const widthValue = parseFloat(finalWidth);
        if (!isNaN(widthValue) && widthValue > 1500) {
          finalWidth = '1500';
          if (this.imageForm.keepAspectRatio && this.imageForm.originalWidth > 0 && this.imageForm.originalHeight > 0) {
            const aspectRatio = this.imageForm.originalHeight / this.imageForm.originalWidth;
            finalHeight = Math.round(1500 * aspectRatio).toString();
          }
          this.$message.warning('图片宽度已限制为1500px');
        }
      }

      const styles = [];
      if (this.imageForm.border) {
        const border = this.imageForm.border.includes('solid') ||
        this.imageForm.border.includes('dashed') ||
        this.imageForm.border.includes('dotted')
          ? this.imageForm.border
          : `${this.imageForm.border}px solid #000`;
        styles.push(`border: ${border}`);
      }
      if (this.imageForm.margin) {
        const margin = this.imageForm.margin.includes('px') ||
        this.imageForm.margin.includes('%') ||
        this.imageForm.margin.includes('auto')
          ? this.imageForm.margin
          : `${this.imageForm.margin}px`;
        styles.push(`margin: ${margin}`);
      }

      const styleStr = styles.length ? `style="${styles.join('; ')}"` : '';
      const altStr = this.imageForm.alt ? `alt="${this.imageForm.alt}"` : '';
      const widthStr = finalWidth ? `width="${finalWidth}"` : '';
      const heightStr = finalHeight && !this.imageForm.keepAspectRatio ? `height="${finalHeight}"` : '';

      const keepHeightAttr = !this.imageForm.keepAspectRatio ? 'data-keep-height="true"' : '';
      const imgHtml = `<img src="${this.imageForm.url}" ${widthStr} ${heightStr} ${styleStr} ${altStr}  />`;

      if (this.contextMenuImageNode && this.contextMenuImageNode.parentNode) {
        this.quill.deleteText(this.selectionIndex, 1, 'user');
        this.quill.clipboard.dangerouslyPasteHTML(this.selectionIndex, imgHtml);
      } else {
        this.quill.clipboard.dangerouslyPasteHTML(this.selectionIndex, imgHtml);
      }

      this.$nextTick(() => {
        const [leaf] = this.quill.getLeaf(this.selectionIndex + 1);
        if (leaf && leaf.domNode && leaf.domNode.tagName === 'IMG') {
          const newImage = leaf.domNode;

          if (finalWidth) {
            newImage.setAttribute('width', finalWidth);
            newImage.style.width = '';
          }
          if (finalHeight && !this.imageForm.keepAspectRatio) {
            newImage.setAttribute('height', finalHeight);
            newImage.style.height = '';
          }
          // 设置data-keep-height属性
          if (!this.imageForm.keepAspectRatio) {
            newImage.setAttribute('data-keep-height', 'true');
          } else {
            newImage.removeAttribute('data-keep-height');
          }

          if (this.imageForm.border) {
            const border = this.imageForm.border.includes('solid') ||
            this.imageForm.border.includes('dashed') ||
            this.imageForm.border.includes('dotted')
              ? this.imageForm.border
              : `${this.imageForm.border}px solid #000`;
            newImage.style.border = border;
          }
          if (this.imageForm.margin) {
            const margin = this.imageForm.margin.includes('px') ||
            this.imageForm.margin.includes('%') ||
            this.imageForm.margin.includes('auto')
              ? this.imageForm.margin
              : `${this.imageForm.margin}px`;
            newImage.style.margin = margin;
          }
          if (this.imageForm.alt) {
            newImage.alt = this.imageForm.alt;
          }

          this.content = this.$refs.editor.children[0].innerHTML;
          this.$emit("input", this.content);
        }
      });

      this.quill.setSelection(this.selectionIndex + 1);
      this.imageDialogVisible = false;
      this.content = this.$refs.editor.children[0].innerHTML;
      this.$emit("input", this.content);

      this.$nextTick(() => {
        const html = this.$refs.editor.children[0].innerHTML;
        this.content = html;
        this.$emit("input", html);
        this.$emit("on-change", { html, text: this.quill.getText(), quill: this.quill });
      });

      this.contextMenuImageNode = null;
    },

    handleDialogClose(done) {
      this.imageForm = {
        url: "",
        width: "",
        height: "",
        widthUnit: "px",
        heightUnit: "px",
        keepAspectRatio: true,
        originalWidth: 0,
        originalHeight: 0,
        border: "",
        margin: "",
        alt: ""
      };

      if (done) {
        done();
      } else {
        this.imageDialogVisible = false;
      }
    },

    handleBeforeUpload(file) {
      const type = ["image/jpeg", "image/jpg", "image/png", "image/svg+xml"];
      const isJPG = type.includes(file.type);
      if (!isJPG) {
        this.$message.error(`图片格式错误! 支持的格式: JPG、PNG、SVG`);
        return false;
      }
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 >= this.fileSize;
        if (!isLt) {
          this.$message.error(`上传文件大小不能小于 ${this.fileSize} MB!`);
          return false;
        }
      }
      return true;
    },

    handleUploadSuccess(res) {
      if (res.code == 200) {
        let quill = this.quill;
        let length = quill.getSelection().index;
        quill.insertEmbed(length, "image", process.env.VUE_APP_BASE_API + res.fileName);
        quill.setSelection(length + 1);
      } else {
        this.$message.error("图片插入失败");
      }
    },

    handleContentImageUpload(file) {
      const isImage = file.type.startsWith('image/');
      if (!isImage) {
        this.$message.error('只能上传图片文件!');
        return false;
      }

      const maxSize = 5 * 1024 * 1024;
      if (file.size > maxSize) {
        this.$message.error('图片大小不能超过5MB!');
        return false;
      }

      return true;
    },

    async uploadLocalImagesToOSS(htmlContent) {
      const localImageRegex = /<img[^>]*src=["'](\/dev-api\/profile\/upload\/[^"']+)["'][^>]*>/g;
      let match;
      let newHtmlContent = htmlContent;
      const uploadPromises = [];
      const processedPaths = new Set();

      while ((match = localImageRegex.exec(htmlContent)) !== null) {
        const fullImgTag = match[0];
        const localPath = match[1];

        if (processedPaths.has(localPath)) {
          continue;
        }
        processedPaths.add(localPath);

        const uploadPromise = new Promise((resolve) => {
          const img = new Image();
          img.crossOrigin = 'anonymous';
          img.onload = async () => {
            try {
              const response = await fetch(localPath);
              const blob = await response.blob();
              const fileName = localPath.split('/').pop() || `content_image_${Date.now()}.jpg`;
              const file = new File([blob], fileName, { type: blob.type });

              const uploadResult = await uploadContentImage(file);
              if (uploadResult.code === 200) {
                const newImgTag = fullImgTag.replace(localPath, uploadResult.url);
                newHtmlContent = newHtmlContent.replace(new RegExp(localPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), uploadResult.url);
                console.log(`图片路径已替换: ${localPath} -> ${uploadResult.url}`);
              }
              resolve();
            } catch (error) {
              console.error('图片上传失败:', error);
              resolve();
            }
          };
          img.onerror = () => {
            console.warn('无法加载本地图片:', localPath);
            resolve();
          };
          img.src = localPath;
        });

        uploadPromises.push(uploadPromise);
      }

      if (uploadPromises.length > 0) {
        await Promise.all(uploadPromises);
      }

      return newHtmlContent;
    },

    handleUploadError() {
      this.$message.error("图片上传失败，请重试");
    },

    getContent() {
      if (this.quill) {
        const html = this.$refs.editor.children[0].innerHTML;
        this.content = html;
        return html;
      }
      return this.content;
    },

    setContent(content) {
      this.content = content || "";
      if (this.quill) {
        this.quill.clipboard.dangerouslyPasteHTML(this.content);
      }
    },
  }
};
</script>

<style>
/* 自定义首行缩进样式 */
.ql-editor p {
  text-indent: 0; /* 重置默认缩进 */
}

.ql-editor .ql-indent-indent {
  text-indent: 2em;
}

.ql-editor .ql-indent-indent:first-line {
  text-indent: 2em;
}
.ql-formatAll::before {
  content: "排";
  font-size: 14px;
}

.editor,
.ql-toolbar {
  white-space: pre-wrap !important;
  line-height: normal !important;
}

.image-preview {
  margin-top: 15px;
  padding: 10px;
  border: 1px dashed #e6e6e6;
  border-radius: 4px;
}

.preview-img {
  max-height: 200px;
  transition: all 0.3s ease;
}

.dialog-footer {
  text-align: right;
}

/* 右键菜单样式 */
.context-menu {
  background: #fff;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 8px 16px;
  cursor: pointer;
  font-size: 14px;
  color: #606266;
  min-width: 80px;
  text-align: center;
}

.context-menu:hover {
  background: #f5f7fa;
  color: #409eff;
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
  content: "宋体";
  font-family: "SimSun", serif;
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
  content: "黑体";
  font-family: "SimHei", sans-serif;
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
  content: "微软雅黑";
  font-family: "Microsoft YaHei", sans-serif;
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
  content: "楷体";
  font-family: "KaiTi", serif;
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
  content: "仿宋";
  font-family: "FangSong", serif;
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
  content: "Arial";
  font-family: "Arial", sans-serif;
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="12px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="12px"]::before {
  content: "12px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {
  content: "14px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]::before {
  content: "16px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]::before {
  content: "20px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="24px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="24px"]::before {
  content: "24px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="32px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="32px"]::before {
  content: "32px";
}


.ql-editor {
  width: 100%;
}
</style>


<!-- 全局样式，修复弹窗内编辑器下拉框显示问题 -->
<style>
/* 修复Quill编辑器下拉框在弹窗内的显示问题 */
.ql-snow .ql-picker {
  z-index: 9999 !important;
}

.ql-snow .ql-picker-options {
  z-index: 9999 !important;
  max-height: 200px !important;
  overflow-y: auto !important;
}

/* 确保下拉框在弹窗内正确显示 */
.el-dialog .ql-snow .ql-picker {
  z-index: 9999 !important;
}

.el-dialog .ql-snow .ql-picker-options {
  z-index: 9999 !important;
  position: absolute !important;
  top: 100% !important;
  left: 0 !important;
  right: 0 !important;
  max-height: 200px !important;
  overflow-y: auto !important;
  background: white !important;
  border: 1px solid #ccc !important;
  border-radius: 4px !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
}

/* 确保编辑器容器不会裁剪下拉框 */
.el-dialog .enhanced-editor {
  overflow: visible !important;
}

.el-dialog .editor-container {
  overflow: visible !important;
}
</style>
